package nl.cypherpunk.statelearner.fuzzing;
import java.io.File;
import java.io.IOException;
import java.util.*;

import net.automatalib.words.Alphabet;
import net.automatalib.words.impl.Alphabets;
import nl.cypherpunk.statelearner.StateLearnerSUL;
import nl.cypherpunk.statelearner.tls.TLSConfig;
import nl.cypherpunk.statelearner.fuzzing.TLSFuzzingService;

public class TLSSUT implements StateLearnerSUL<String, String>{
    Alphabet<String> alphabet;
    TLSFuzzingService tls;
    Alphabet<String> meaning;
    Boolean isTrash = false;
    public TLSSUT(TLSConfig config) throws Exception {
        alphabet = Alphabets.fromList(Arrays.asList(config.alphabet.split(" ")));
        meaning = Alphabets.fromList(Arrays.asList(config.meaning.split(" ")));
        tls = new TLSFuzzingService();

        tls.setTarget(config.target);
        tls.setHost(config.host);
        tls.setPort(config.port);
        tls.setCommand(config.cmd);
        tls.setRequireRestart(config.restart);
        tls.setReceiveMessagesTimeout(config.timeout);
        tls.setKeystore(config.keystore_filename, config.keystore_password);
        tls.setConsoleOutput(config.console_output);
        tls.setRedirectFile(config.redirectFile);
        tls.setCoverageCmd(config.coverage_cmd);
        if(config.version.equals("tls10")) {
            tls.useTLS10();
        }
        else {
            tls.useTLS12();
        }

        tls.start();
    }

    public Alphabet<String> getAlphabet() {
        return alphabet;
    }
    public Alphabet<String> getMeaning() {
        return meaning;
    }

    public boolean canFork() {
        return false;
    }

    public String stepConcrete(String symbol, LinkedHashMap<byte[] , Double> seed, boolean flag) {
        String result = null;
        try {
            result = tls.processSymbol(symbol, seed, flag);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public void exit()
    {
        tls.close();
    }

    public void restart() throws Exception {
        tls.start();
    }

    public void setInitScore(Double score){
        tls.initScore = score;
    }

    public int getCoverage() throws IOException {
        return tls.getCoverage();
    }

    @Override
    public String step(String symbol) {
        return symbol;
    }

    @Override
    public void pre() {
        try {
            tls.reset();
        } catch (Exception e) {
            //e.printStackTrace();
            try {
                tls.reset();
            }catch (Exception ee) {
                ee.printStackTrace();
                isTrash = true;
                throw new RuntimeException(ee);
            }
            //throw new RuntimeException(e);
        }
    }
    @Override
    public void post() {

    }


}
